package com.seems.janggu;

import java.util.ArrayList;
import java.util.List;

import android.util.Log;

public class HitInfo {
	private String TAG = "HitIfno";
	private static HitInfo mHitInfo;
	private ArrayList<HitItem> mHitList;
	
	private HitInfo(){
		mHitList = new ArrayList<HitItem>();
	}
	
	public static HitInfo getInstance() {
		if(mHitInfo == null){
			mHitInfo = new HitInfo();
		}
		
		return mHitInfo;
	}
	
	public void addHitItem(HitItem hitItem) {
		mHitList.add(hitItem);
		//mVisualHitList.add(hitItem);
	}
	
	public void addHitItem(int hitType, float pressure, long milliSec) {
		HitItem hitItem = new HitItem(hitType, pressure, milliSec);
		mHitList.add(hitItem);
	}

	public void removeHitItem(HitItem hitItem) {
		mHitList.remove(hitItem);
		//mVisualHitList.remove(hitItem);
	}
	
	private int binarySearchWithMilliSec(int minIndex, int maxIndex, long milliSec){
		HitItem item;
		int midIndex = -1;
		
		while(minIndex <= maxIndex){
			midIndex = minIndex + (maxIndex - minIndex)/2;
			item = mHitList.get(midIndex);
			if(item.getMilliSec() > milliSec) {
				if(minIndex == midIndex) break;
				minIndex = midIndex;
			} else if(item.getMilliSec() < milliSec) {
				if(maxIndex == midIndex) break;
				maxIndex = midIndex;
			} else {
				break;
			}
		}
		
		if(minIndex == maxIndex){
			return minIndex;
		}
		
		return midIndex;
	}
	
	public HitItem getHitItem(int index){
		try {
			return mHitList.get(index);
		} catch(Exception e) {
			return null;
		}
	}
	
	public void reset(){
		mHitList.clear();
	}
	
	public HitItem getNextHitItem(long milliSec){
		int i;
		for(i = 0; i < mHitList.size(); i++){
			if(mHitList.get(i).getMilliSec() > milliSec){
				break;
			}
		}
		
		if(i == mHitList.size()){
			return null; 
		}
		
		return mHitList.get(i);
	}
	
	public List<HitItem> getHitList(long from, long to){
		int size = mHitList.size();
		int fromIndex, toIndex;
		HitItem hitItem;
		int i;
		
		if(from < 0){
			from = 0;
		}
		
		if(size == 0){
			return null;
		}
		/*
		fromIndex = binarySearchWithMilliSec(0, size, from);
		if(fromIndex < 0){
			return null;
		}
		
		toIndex = binarySearchWithMilliSec(fromIndex, size, to);
		if(toIndex < 0){
			return null;
		}
		*/
		
		for(i = 0; i < size; i++){
			hitItem = mHitList.get(i);
			//Log.d(TAG, "from : " + from + ", item : " + hitItem.getMilliSec());
			if(hitItem.getMilliSec() > from) break;
		}
		
		if(i == size){
			return null;
		}
		
		fromIndex = i;
		
		for(i = size - 1; i >= 0; i--){
			hitItem = mHitList.get(i);
			//Log.d(TAG, "to : " + to + ", item : " + hitItem.getMilliSec());
			if(hitItem.getMilliSec() < to) break;
		}
		
		if(i == -1) {
			return null;
		}
		
		toIndex = i;
		
		//Log.d(TAG, ""+fromIndex + " - " + toIndex);
		return mHitList.subList(fromIndex, toIndex+1);			
	}

	public class HitItem {
		private int mHitType;
		private float mPressure;
		private long mInterval;
		private long mMilliSec;
		public final static int HIT_TYPE_DUNG = 0;
		public final static int HIT_TYPE_GI = 1;
		public final static int HIT_TYPE_GUNG = 2;
		public final static int HIT_TYPE_DDA = 3;

		public HitItem(int hitType, float pressure, long milliSec) {
			mHitType = hitType;
			mPressure = pressure;
			mMilliSec = milliSec;
			//mMilliSec = System.currentTimeMillis();
		}

		public void setInterval(long interval) {
			mInterval = interval;
		}

		public long getInterval() {
			return mInterval;
		}

		public int getHitType() {
			return mHitType;
		}

		public float getPressure() {
			return mPressure;
		}

		public long getMilliSec() {
			return mMilliSec;
		}
	}
}
